package com.service;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Timer;
import java.util.TimerTask;

@Service
public class RabbitMQService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

//    long[] times={1000,1000*10,10000*100,1000*1000,1000*10000};
    long[] times={1000,1000*10,1000*10,1000*10,1000*10};

//   第一次来 是下标0  一秒    第二次  10秒   这个是留给我让我们处理异常的，五次全部使用过后就认为这个服务器，挂了
    /**
     * 发送消息
     * @param exchcange
     * @param key
     * @param msg
     */
    public void sendMessage(String exchcange,String key,Message msg){
        //交换机不存在的反映
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if (b==false){
                    System.out.println("交换机不存在！");
                }
            }
        });
//未读取   未反馈
        // key 不存在时 反映
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.out.println("key搞错答");
            }
        });

        rabbitTemplate.convertAndSend(exchcange,key,msg);

    }

    /**
     * 监听消息
     * @param msg
     * @param channel
     * @throws Exception
     */
    @RabbitListener(queues = "s2020_2_3_queue")
    @RabbitHandler
    public void recevieMQ(Message msg, Channel channel) throws Exception {
        try {
            int n = 1 / 0;
            // 已经正常处理好消息：消息编号/是否批量处理所以比当前编号小的消息
            channel.basicAck(msg.getMessageProperties().getDeliveryTag(),false);
        }catch (Exception e){
//            有异常就重发,一般不用下面这个会死循环，后面消息也无法读取
//            channel.basicReject(msg.getMessageProperties().getDeliveryTag(),true);

            String uuid=msg.getMessageProperties().getMessageId();
            System.out.println("UUId:"+uuid);

            Integer count=(Integer) redisTemplate.boundValueOps(uuid).get();

            System.out.println("count:"+count);
            if (count==null){
                count=0;
            }
//            我也这样，他不是保存到了redis吗
            count++;
            final int s=count;
            System.out.println("s:"+s);
            if (count<5){

                //删除信息
                /*channel.basicNack(msg.getMessageProperties()
                        .getDeliveryTag(),false,false);*/
                System.out.println("消息编号："+msg.getMessageProperties().getDeliveryTag());
                String str=new String(msg.getBody(),"utf-8");
                System.out.println("收到消息:"+str);

                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        redisTemplate.boundValueOps(uuid).set(s);
                        //丢弃消息：消息编号，是否批量，是否chong'f重发，一般不用true，重试次要自己处理好
                        try{
                            channel.basicNack(msg.getMessageProperties().getDeliveryTag(),false,false);
                            //重发
                            rabbitTemplate.convertAndSend(msg.getMessageProperties().getReceivedExchange(),msg.getMessageProperties().getReceivedRoutingKey(),msg);

                        }catch (IOException el){
                            el.printStackTrace();
                        }
             }
                },times[count-1]);


            } else{
                System.out.println("另外处理");
                return;
            }
        }
    }


}
